﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Drawing;
using System.Linq;
using System.Windows.Forms;

using System.IO;
using System.Xml;
using System.Xml.Linq;
using System.Diagnostics;

using tester;

namespace FontTool
{
    public partial class FontToolMain : Form
    {

        #region variables
        private nFont newFont;
        private XDocument oldDoc;
        private string oldDocPath = "";

        private int imgWidth = 0; //the width of preview img
        private int imgOrigin = 0; //original img width at 100% used for resizing and showing info


        private string uriFilters = @"XML\Filters.xml";
        private Dictionary<string, Filter> Filters = new Dictionary<string, Filter>();
        private string currentFilter = "NONE";

        private string[] _GlyphMenu = { "Add...", "Add origin...", "Replace...", "Remove...", "Edit...", "Open in Editor..." };
        private string[] _zoomMenu = { "25%", "50%", "75%", "100%", "125%", "150%", "175%", "200%" };
        private float imageScale = 1f;
        private float imageScaleIncr = 1.2f;
        private float imageScaleDescr = 0.8f;
        private float imageScaleWrite = 1f;

        private bool drawLines = true;
        private bool runInDebug = false;
        private FileSystemWatcher watcher = new FileSystemWatcher();
        #endregion

        #region Contructors
        public FontToolMain()
        {
            InitializeComponent();

#if DEBUG
            runInDebug = true;
#endif

            enableControls(false);
            loadFilterXML();
            loadDummySetsXML();

            //creates empty lines with default parameters
            initEmptyLines();
            //inits message tooptips for controls
            initTooltips();
            //inits gridview, zoom, preview context menu
            initContextMenus();
            //timer used for delaying update by ms to make it appear all the time
            initUpdatePreviewTimer();
        }

        private void initUpdatePreviewTimer()
        {
            timerUpdatePreview.Enabled = runInDebug;
            timerUpdatePreview.Interval = 100;
            timerUpdatePreview.Tick += new EventHandler((o, s) =>
            {
                UpdatePreviewWindow();
                timerUpdatePreview.Stop();
                timerUpdatePreview.Enabled = false;
            });
        }

        private void initContextMenus()
        {

            gridViewContextMenu.Items.Clear();
            for (int i = 0; i < _GlyphMenu.Length; i++)
                gridViewContextMenu.Items.Add(_GlyphMenu[i]);
            gridViewContextMenu.ItemClicked += new ToolStripItemClickedEventHandler(gridViewContextMenu_ItemClicked);

            zoomContextMenu.Items.Clear();
            for (int i = 0; i < _zoomMenu.Length; i++)
                zoomContextMenu.Items.Add(_zoomMenu[i]);
            zoomContextMenu.ItemClicked += new ToolStripItemClickedEventHandler(zoomContextMenu_ItemClicked);

            previewContextMenu.Items.Clear();
            for (int i = 0; i < _zoomMenu.Length; i++)
                previewContextMenu.Items.Add(_zoomMenu[i]);
            previewContextMenu.ItemClicked += new ToolStripItemClickedEventHandler(previewContextMenu_ItemClicked);
        }
        #endregion

        #region propertyGrid handlers
        private void initPropertyGrid(Object obj)
        {
            newFont.PropertyChanged += new PropertyChangedEventHandler(newFont_PropertyChanged);
            propertyGrid1.SelectedObject = obj;
            DoExpandORCollapse();
        }

        void newFont_PropertyChanged(object sender, PropertyChangedEventArgs e)
        {
            UpdateFontXML("Font", "", e.PropertyName, newFont.getChangedValue(e.PropertyName));
        }

        public void DoExpandORCollapse()
        {
            GridItem root = this.propertyGrid1.SelectedGridItem;
            while (root.Parent != null)
            {
                root = root.Parent;
            }
            root.GridItems[0].Expanded = true; //first category
            root.GridItems[1].Expanded = false;
            root.GridItems[2].Expanded = false;
        }

        private void propertyGrid1_PropertyValueChanged(object s, PropertyValueChangedEventArgs e)
        {
            if (e.ChangedItem.Label == "selectedLine")
            {
                switch ((nFont.Lines)e.ChangedItem.Value)
                {
                    case nFont.Lines._Leading:
                        setAllLinesUnmovable();
                        _Leading.movable = true;
                        break;
                    case nFont.Lines._xHeight:
                        setAllLinesUnmovable();
                        _xHeight.movable = true;
                        break;
                    case nFont.Lines._capHeight:
                        setAllLinesUnmovable();
                        _capHeight.movable = true;
                        break;
                    case nFont.Lines._ascenderHeight:
                        setAllLinesUnmovable();
                        _ascenderHeight.movable = true;
                        break;
                    case nFont.Lines._descenderHeight:
                        setAllLinesUnmovable();
                        _descenderHeight.movable = true;
                        break;
                    case nFont.Lines.None:
                        setAllLinesUnmovable();
                        break;
                    default:
                        break;
                }
            }
            //reinitialization to make them with the latest parameters
            UpdatePreviewWindow();
        }
        #endregion

        #region ToolStripMenu_Click
        /***************************OPEN, SAVE, CLOSE MENU LISTENERS******************************************/
        private void openToolStripMenuItem_Click(object sender, EventArgs e)
        {
            loadFontXML();
        }

        private void saveToolStripMenuItem_Click(object sender, EventArgs e)
        {
            reSaveFontXML();
            MessageBox.Show("Saved!");
        }

        private void closeToolStripMenuItem_Click(object sender, EventArgs e)
        {
            this.Dispose();
        }
        /************************CREATE: EMPTY, FROM FONTSPLITTER, FROM FONT, FROM IMAGES LISTENERS*********************************************/
        private void emptyToolStripMenuItem_Click(object sender, EventArgs e)
        {
            newFont = new nFont();
            newFont.guessFontValues();
            createFontXML();
            InitViews();
        }

        private void FontSplitterStripMenuItem_Click(object sender, EventArgs e)
        {
            tester.Form1 splitter = new Form1();
            splitter.sendImagesDirectory = new Form1.sendSplitImage(receiveSplitImage);

            splitter.Show();
        }

        private void fromFontToolStripMenuItem_Click(object sender, EventArgs e)
        {
            using (ttf2png t2p = new ttf2png())
            {
                t2p.sendFontDirWithInfo = new ttf2png.sendSplitFont(receiveFontDirWithInfo);

                if (t2p.ShowDialog() == System.Windows.Forms.DialogResult.Cancel)
                    Console.WriteLine("dialog closed");
            }
        }

        private void frompngsToolStripMenuItem_Click(object sender, EventArgs e)
        {
            createFontFromImg();
        }
        /*************************UNDO, REDO LISTENERS********************************************/
        private void undoToolStripMenuItem_Click(object sender, EventArgs e)
        {
            newFont.cmdManager.Undo(newFont);
            timerUpdatePreview.Start();
        }

        private void redoToolStripMenuItem_Click(object sender, EventArgs e)
        {
            newFont.cmdManager.Redo(newFont);
            timerUpdatePreview.Start();
        }
        #endregion

        #region FontTool_2_Resize \ splitContainer1_SplitterMoved
        private void FontTool_2_Resize(object sender, EventArgs e)
        {
            if (this.WindowState != FormWindowState.Minimized)
            {
                offScreenBmp = new Bitmap(panelPreview.Width, panelPreview.Height);
                gfx = Graphics.FromImage(offScreenBmp);
            }
            if (newFont != null)
            {
                updateDataGridView();

                if(imgTiles != null)
                    initImgTiles();

                _SpaceBeginLocation = 0;
                _KerningBeginLocation = 0;
                timerUpdatePreview.Start();
            }
        }

        private void splitContainer1_SplitterMoved(object sender, SplitterEventArgs e)
        {
            if (newFont != null)
            {
                offScreenBmp = new Bitmap(panelPreview.Width, panelPreview.Height);
                gfx = Graphics.FromImage(offScreenBmp);
                //updateDataGridView();

                if(imgTiles != null)
                    initImgTiles();
                timerUpdatePreview.Start();
            }
        }
        #endregion

        #region XML handlers (save, load, update, resave)
        /*************************************************************************************************************************************/
        /*
         * First place where LinQ comes into the picture;
         * Using saveFileDialog window to save xml file;
         * Lambda expression used to save list of all characters;
         * Question is - can\should I use this method when I will want to update the file?
         */
        private void saveFontXML()
        {
            using (SaveFileDialog sfd = new SaveFileDialog())
            {
                sfd.Title = "Save XML file";
                sfd.Filter = "Xml Files (.xml)|*.xml|All Files (*.*)|*.*";
                sfd.FilterIndex = 0;

                XDocument xdoc = new XDocument(
                    new XElement("Font",
                        new XAttribute("Name", newFont._Name),
                        new XAttribute("Space", newFont._Space),
                        new XAttribute("Kerning", newFont._Kerning),
                        new XAttribute("Leading", newFont._Leading),
                        new XAttribute("xHeight", newFont._xHeight),
                        new XAttribute("capHeight", newFont._capHeight),
                        new XAttribute("ascenderHeight", newFont._ascenderHeight),
                        new XAttribute("descenderHeight", newFont._descenderHeight),

                        new XAttribute("FontOriginName", newFont.FontOriginName),
                        new XAttribute("FontOriginBold", newFont.FontOriginBold),
                        new XAttribute("FontOriginItalic", newFont.FontOriginItalic),
                        new XAttribute("FontOriginSize", newFont.FontOriginSize),
                        new XAttribute("FontOriginColor", newFont.FontOriginColor),

                        newFont._Characters.Select(item =>
                            new XElement("Character",
                            new XAttribute("unicode", item._Name),
                            new XAttribute("anchorPointX", item._AnchorPoint.X),
                            new XAttribute("anchorPointY", item._AnchorPoint.Y),
                            new XAttribute("width", item._Width)))));

                if (sfd.ShowDialog() == System.Windows.Forms.DialogResult.OK)
                {
                    xdoc.Save(sfd.FileName + ".xml");
                }
            }
        }

        /*
         * Similar to saveXML method;
         * Using also Linq;?
         * Returns created Font object and also initializes it as the newFont
         * which is used as the source of info for all the windows;
         */
        private void loadFontXML()
        {
            nFont font = new nFont();

            using (OpenFileDialog ofd = new OpenFileDialog())
            {
                ofd.Title = "Open XML file";
                ofd.Filter = "Xml Files (.xml)|*.xml|All Files (*.*)|*.*";
                ofd.FilterIndex = 0;

                if (ofd.ShowDialog() == System.Windows.Forms.DialogResult.OK)
                {
                    XDocument xdoc = XDocument.Load(ofd.FileName);
                    oldDoc = xdoc;              //for saving later purposes
                    oldDocPath = ofd.FileName;  //for saving later purposes
                    font._Name = xdoc.Element("Font").Attribute("Name").Value;
                    font._Space = float.Parse(xdoc.Element("Font").Attribute("Space").Value);
                    font._Kerning = float.Parse(xdoc.Element("Font").Attribute("Kerning").Value);
                    font._Leading = float.Parse(xdoc.Element("Font").Attribute("Leading").Value);
                    font._xHeight = float.Parse(xdoc.Element("Font").Attribute("xHeight").Value);
                    font._capHeight = float.Parse(xdoc.Element("Font").Attribute("capHeight").Value);
                    font._ascenderHeight = float.Parse(xdoc.Element("Font").Attribute("ascenderHeight").Value);
                    font._descenderHeight = float.Parse(xdoc.Element("Font").Attribute("descenderHeight").Value);

                    font.FontOriginName = xdoc.Element("Font").Attribute("FontOriginName").Value;
                    font.FontOriginBold = bool.Parse(xdoc.Element("Font").Attribute("FontOriginBold").Value);
                    font.FontOriginItalic = bool.Parse(xdoc.Element("Font").Attribute("FontOriginItalic").Value);
                    font.FontOriginSize = float.Parse(xdoc.Element("Font").Attribute("FontOriginSize").Value);
                    font.FontOriginColor = int.Parse(xdoc.Element("Font").Attribute("FontOriginColor").Value);

                    foreach (XElement child in xdoc.Element("Font").Elements())
                    {
                        nCharacter c = new nCharacter(child.Attribute("unicode").Value,
                                float.Parse(child.Attribute("anchorPointX").Value),
                                float.Parse(child.Attribute("anchorPointY").Value),
                                float.Parse(child.Attribute("width").Value));
                        c._ImageUri = Path.GetDirectoryName(ofd.FileName) + @"\" + c._Name + ".png"; //taking xml file directory and adding to it file names; 
                        c.guessOnlyHeight();
                        font._Characters.Add(c);
                    }
                    newFont = font;
                    refreshList();

                    InitViews();
                    timerUpdatePreview.Start();
                    initWatcher(Path.GetDirectoryName(oldDocPath));
                }
            }
        }

        /*
         * Almost identical method to the top one.
         * The only difference is that this one makes it easier for testing since it takes string and 
         * loads it right away instead of waiting for me to openFileDialog;
         */
        private void loadFontXML(string uri)
        {
            nFont font = new nFont();
            XDocument xdoc = XDocument.Load(uri);
            string path = uri;
            oldDoc = xdoc;
            oldDocPath = path;

            font._Name = xdoc.Element("Font").Attribute("Name").Value;
            font._Space = float.Parse(xdoc.Element("Font").Attribute("Space").Value);
            font._Kerning = float.Parse(xdoc.Element("Font").Attribute("Kerning").Value);
            font._Leading = float.Parse(xdoc.Element("Font").Attribute("Leading").Value);
            font._xHeight = float.Parse(xdoc.Element("Font").Attribute("xHeight").Value);
            font._capHeight = float.Parse(xdoc.Element("Font").Attribute("capHeight").Value);
            font._ascenderHeight = float.Parse(xdoc.Element("Font").Attribute("ascenderHeight").Value);
            font._descenderHeight = float.Parse(xdoc.Element("Font").Attribute("descenderHeight").Value);

            font.FontOriginName = xdoc.Element("Font").Attribute("FontOriginName").Value;
            font.FontOriginBold = bool.Parse(xdoc.Element("Font").Attribute("FontOriginBold").Value);
            font.FontOriginItalic = bool.Parse(xdoc.Element("Font").Attribute("FontOriginItalic").Value);
            font.FontOriginSize = float.Parse(xdoc.Element("Font").Attribute("FontOriginSize").Value);
            font.FontOriginColor = int.Parse(xdoc.Element("Font").Attribute("FontOriginColor").Value);

            foreach (XElement child in xdoc.Element("Font").Elements())
            {
                nCharacter c = new nCharacter(child.Attribute("unicode").Value,
                        float.Parse(child.Attribute("anchorPointX").Value),
                        float.Parse(child.Attribute("anchorPointY").Value),
                        float.Parse(child.Attribute("width").Value));
                c._ImageUri = Path.GetDirectoryName(path) + @"\" + c._Name + ".png"; //taking xml file directory and adding to it file names;
                c.guessOnlyHeight();
                font._Characters.Add(c);
            }
            newFont = font;
            refreshList();
            initWatcher(Path.GetDirectoryName(oldDocPath));
        }

        private void createFontXML()
        {
            XDocument xdoc = new XDocument(
                new XElement("Font",
                    new XAttribute("Name", newFont._Name),
                    new XAttribute("Space", newFont._Space),
                    new XAttribute("Kerning", newFont._Kerning),
                    new XAttribute("Leading", newFont._Leading),
                    new XAttribute("xHeight", newFont._xHeight),
                    new XAttribute("capHeight", newFont._capHeight),
                    new XAttribute("ascenderHeight", newFont._ascenderHeight),
                    new XAttribute("descenderHeight", newFont._descenderHeight),

                    new XAttribute("FontOriginName", newFont.FontOriginName),
                    new XAttribute("FontOriginBold", newFont.FontOriginBold),
                    new XAttribute("FontOriginItalic", newFont.FontOriginItalic),
                    new XAttribute("FontOriginSize", newFont.FontOriginSize),
                    new XAttribute("FontOriginColor", newFont.FontOriginColor),

                    newFont._Characters.Select(item =>
                        new XElement("Character",
                        new XAttribute("unicode", item._Name),
                        new XAttribute("anchorPointX", item._AnchorPoint.X),
                        new XAttribute("anchorPointY", item._AnchorPoint.Y),
                        new XAttribute("width", item._Width)))));

            oldDoc = xdoc;
            oldDocPath = "";
        }

        /*
         * Just as title says this method will handle update of xml file;
         * whenever we change something the data should be saved;
         * need to also prevent from saving in again if it hasn't been changed;
         */
        private void UpdateFontXML(string Element, string ElementChild, string attribute, object value)
        {
            oldDoc.Element(Element).Attribute(attribute).SetValue(value);
            if (ElementChild != "")
                oldDoc.Element(Element).Element(ElementChild).Attribute(attribute).SetValue(value);
        }

        private void reSaveFontXML()
        {
            oldDoc.Element("Font").Elements().Remove();
            oldDoc.Element("Font").Add(newFont._Characters.Select(item =>
                            new XElement("Character",
                            new XAttribute("unicode", item._Name),
                            new XAttribute("anchorPointX", item._AnchorPoint.X),
                            new XAttribute("anchorPointY", item._AnchorPoint.Y),
                            new XAttribute("width", item._Width))));

            if (oldDocPath == "")
            {
                using (SaveFileDialog sfd = new SaveFileDialog())
                {
                    string tempPath = "";
 
                    sfd.Title = "Save XML file";
                    sfd.Filter = "Xml Files (.xml)|*.xml|All Files (*.*)|*.*";
                    sfd.FilterIndex = 0;

                    if (sfd.ShowDialog() == System.Windows.Forms.DialogResult.OK)
                    {
                        tempPath = Path.GetDirectoryName(sfd.FileName);
                        cleanDirectoryImages(tempPath);
                        oldDoc.Save(sfd.FileName);
                    }

                    foreach (nCharacter c in newFont.Characters)
                    {
                        if (!File.Exists(tempPath + @"\" + c._Name + ".png"))
                        {
                            File.Copy(c._ImageUri, tempPath+@"\" + c._Name + ".png");
                        }
                    }
                }
            }
            if (oldDocPath != "")
            {
                cleanDirectoryImages(Path.GetDirectoryName(oldDocPath));
                File.Delete(oldDocPath);
                foreach (nCharacter c in newFont.Characters)
                {
                    if (!File.Exists(Path.GetDirectoryName(oldDocPath) + @"\" + c._Name + ".png"))
                    {
                        File.Copy(c._ImageUri, Path.GetDirectoryName(oldDocPath) + @"\" + c._Name + ".png");
                    }
                }
                oldDoc.Save(oldDocPath);
            }
        }

        private void cleanDirectoryImages(string tempPath)
        {

            string[] dirpngs = Directory.GetFiles(tempPath);
            Console.WriteLine("tempPath\t" + tempPath);

            foreach (string s in dirpngs)
            {
                Console.WriteLine("s\t"+s);
                Console.WriteLine(s);
                if (!newFont.containsCharImgUri(s))
                    File.Delete(s);
            }
        }

        private void loadFilterXML()
        {
            XDocument xdoc = XDocument.Load(uriFilters);

            foreach (XElement flter in xdoc.Element("Filters").Elements())
            {
                Filter filter = new Filter(
                flter.Attribute("Name").Value,
                flter.Attribute("Characters").Value);
                Filters.Add(filter.Name, filter);
            }
            Filters.Add("NONE", new Filter());
        }

        private void loadDummySetsXML()
        {
            XDocument xdoc = XDocument.Load(uriDummySets);
            //xdoc = XDocument.Load(@"D:\[Project]\FontTool\FontTool_2\XML\DummySet.xml");

            foreach (XElement dummy in xdoc.Element("DummySets").Elements())
            {
                dummySet ds = new dummySet(
                dummy.Attribute("Name").Value,
                dummy.Element("Characters").Value);
                DummySets.Add(dummy.Attribute("Name").Value, ds);
            }
        }
        #endregion

        #region Helping methods
        /*
         * Opens fileDialog for selecting images;
         * creates new empty Font;
         * Fills font with selected images
         */
        private void createFontFromImg()
        {
            using (OpenFileDialog OFD = new OpenFileDialog())
            {
                OFD.Multiselect = true;
                OFD.Filter = "JPEG .jpeg|*.jpeg;*.jpg|png .png|*.png|All files (*.*)|*.*";
                OFD.FilterIndex = 2;
                OFD.Title = "Select image files";

                if (OFD.ShowDialog() != System.Windows.Forms.DialogResult.OK)
                {
                    return;
                }

                nFont font = new nFont();
                font.guessFontValues();
                foreach (string link in OFD.FileNames)
                {
                    nCharacter _char = new nCharacter();
                    _char._ImageUri = link;
                    _char._Name = Path.GetFileNameWithoutExtension(link);
                    _char.guessValues();
                    font._Characters.Add(_char);
                }
                newFont = font;
                refreshList();
                createFontXML();

                InitViews();
            }
        }

        private void InitViews()
        {
            //taking a list of characters and making img width the biggest character;
            imgWidth = Helper.getDefaultWidth(newFont.Characters);
            imgOrigin = imgWidth;

            enableControls(true);
            initPropertyGrid(newFont);
            updateDataGridView();
            UpdatePreviewWindow();
        }

        private void refreshList()
        {
            Helper.sortCharacterList(newFont._Characters);
        }

        /*
         * When starting a project those controls will be disabled by parsing 'False' value;
         * Once a file will be opened or created "True will be parsed;
         */
        private void enableControls(bool enable)
        {
            splitContainer1.Enabled = enable;

            if (enable)
            {
                comboBoxFilterInit();
                comboBoxDummySetsInit();
            }

        }

        private void initTooltips()
        {
            ToolTip TT = new ToolTip();
            TT.IsBalloon = true;
            TT.SetToolTip(buttonMaximizePreview, "maximize the screen");
            TT.SetToolTip(buttonORIGIN, "set preview to default");
            TT.SetToolTip(buttonLinesVisible, @"Show\Hide lines");
            TT.SetToolTip(buttonSetBackground, "set background image");
            TT.SetToolTip(buttonZoomOut, "zoom grid OUT");
            TT.SetToolTip(buttonZoomIn, "zoom grid IN");
            TT.SetToolTip(buttonGridViewOrigin, "set grid to default");
            TT.SetToolTip(textBoxSearch, "enter HEX value and press ENTER");
            TT.SetToolTip(checkBoxDummy, "Use dummy char set?");
            TT.SetToolTip(comboBoxDummySets, "select dummy set..");
            TT.SetToolTip(comboBoxFilter, "select filter...");
            TT.SetToolTip(buttonBGTiles, "Load background from tiles");
            TT.SetToolTip(buttonWriteOnPreview, "when active Press with mouse on preview to write \n press back to deactive");
        }

        private void debugBegin()
        {
            //Opening from XML and then Init() based on the values;
            loadFontXML(@"C:\Users\Min0\Desktop\testFont\newVersion2.xml");
            InitViews();

            timerUpdatePreview.Start();
        }
        #endregion

        private void FontTool_Load(object sender, EventArgs e)
        {
            previewDefault = true;
            offScreenBmp = new Bitmap(panelPreview.Width, panelPreview.Height);
            gfx = Graphics.FromImage(offScreenBmp);

            //startupInfo si = new startupInfo();
            //si.Show();
            if(runInDebug)
            debugBegin();
        }

        //used to respond to delegate call from Editor
        private void requestToUpdatePreview()
        {
            timerUpdatePreview.Start();
        }

        private void receiveFontDirWithInfo(string dir, string fontName, bool bold, bool italic, float size, Color color)
        {
            newFont = new nFont();
            newFont.guessFontValues();
            foreach (string link in Directory.GetFiles(dir))
            {
                nCharacter _char = new nCharacter();
                _char._ImageUri = link;
                _char._Name = Path.GetFileNameWithoutExtension(link);
                _char.guessValues();
                newFont._Characters.Add(_char);
            }
            newFont.FontOriginName = fontName;
            newFont.FontOriginBold = bold;
            newFont.FontOriginItalic = italic;
            newFont.FontOriginSize = size;
            newFont.FontOriginColor = color.ToArgb();
            refreshList();
            createFontXML();
            InitViews();
        }

        private void receiveSplitImage(string dir)
        {
            newFont = new nFont();
            newFont.guessFontValues();
            foreach (string link in Directory.GetFiles(dir))
            {
                nCharacter _char = new nCharacter();
                _char._ImageUri = link;
                _char._Name = Path.GetFileNameWithoutExtension(link);
                _char.guessValues();
                newFont._Characters.Add(_char);
            }

            refreshList();
            createFontXML();

            InitViews();
        }

        private void buttonGuessAnchor_Click(object sender, EventArgs e)
        {
            foreach (nCharacter c in newFont.Characters)
                c.guessAnchorY(newFont.xHeight, newFont.capHeight);

            timerUpdatePreview.Start();
        }

        private void FontToolMain_DragDrop(object sender, DragEventArgs e)
        {
            if (e.Data.GetDataPresent("FileDrop"))
            {

                string[] files = (e.Data.GetData("FileDrop") as string[]);

                if (files.Length == 1 && Path.GetExtension(files[0]) == ".xml")
                {
                    loadFontXML(files[0]);
                    InitViews();
                    timerUpdatePreview.Start();
                }
            }
        }

        private void FontToolMain_DragEnter(object sender, DragEventArgs e)
        {
            e.Effect = DragDropEffects.Copy;
        }

        public bool overTheLine(Point mouseLocation)
        {
            if (checkLine(_Leading, mouseLocation))
                return true;

            if (checkLine(_xHeight, mouseLocation))
                return true;

            if (checkLine(_capHeight, mouseLocation))
                return true;

            if (checkLine(_ascenderHeight, mouseLocation))
                return true;

            if (checkLine(_descenderHeight, mouseLocation))
                return true;

            if (checkLine(_SpaceBegin, mouseLocation))
                return true;

            if (checkLine(_KerningBegin, mouseLocation))
                return true;

            return false;
        }

        private bool checkLine(nLine line, Point mouseLocation)
        {
            Console.WriteLine("Line location: /t"+line.Location.X+":"+line.Location.Y+" | "+line.Width+":"+line.Height);
            Console.WriteLine("Mouse location: /t"+mouseLocation);
            if (mouseLocation.X >= line.Location.X && mouseLocation.X <= line.Width)
                if (mouseLocation.Y >= line.Location.Y || mouseLocation.Y + 2 >= line.Location.Y)
                    if (mouseLocation.Y <= line.Height || mouseLocation.Y - 2 <= line.Height)
                    {
                        return true;
                    }
            return false;
        }

        private void dataGridViewGlyphs_CellMouseEnter(object sender, DataGridViewCellEventArgs e)
        {
            if((dataGridViewGlyphs.Rows[e.RowIndex].Cells[e.ColumnIndex] as customDataGridViewCell).dummyImage != null)
            dataGridViewGlyphs.Rows[e.RowIndex].Cells[e.ColumnIndex].Value = (dataGridViewGlyphs.Rows[e.RowIndex].Cells[e.ColumnIndex] as customDataGridViewCell).dummyImage;
        }

        private void dataGridViewGlyphs_CellMouseLeave(object sender, DataGridViewCellEventArgs e)
        {
            if ((dataGridViewGlyphs.Rows[e.RowIndex].Cells[e.ColumnIndex] as customDataGridViewCell).xmlImage != null)
            dataGridViewGlyphs.Rows[e.RowIndex].Cells[e.ColumnIndex].Value = (dataGridViewGlyphs.Rows[e.RowIndex].Cells[e.ColumnIndex] as customDataGridViewCell).xmlImage;
        }

        private void initWatcher(string directory)
        {
            watcher.Path = directory;
            watcher.Changed += new FileSystemEventHandler(watcher_Changed);
            watcher.EnableRaisingEvents = true;
        }

        void watcher_Changed(object sender, FileSystemEventArgs e)
        {
            DialogResult ds = MessageBox.Show("Files been changed externaly, do you want to reload it?", "Reload", MessageBoxButtons.YesNo);
            
            if (ds == System.Windows.Forms.DialogResult.Yes)
            {
                this.Invoke(new MethodInvoker(updateDataGridView));
            }
        }
    }
}

